package com.qidi.mvcframework.servlet.aop.support;

import com.qidi.mvcframework.servlet.aop.aspect.MyAdvice;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;

public class MyJdkDynamicAopProxy implements InvocationHandler {

    private MyAdviceSupport config;

    public MyJdkDynamicAopProxy(MyAdviceSupport config) {
        this.config = config;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Map<String, MyAdvice> advices = config.getAdvices(method, null);

        Object returnValue;

        try {
            invokeAdvice(advices.get("before"));
            returnValue = method.invoke(config.getTarget(), args);
            invokeAdvice(advices.get("after"));
        } catch (Exception e) {
            invokeAdvice(advices.get("afterThrow"));
            // 这里要把异常抛出去
            throw e;
        }
        return returnValue;
    }

    private void invokeAdvice(MyAdvice advice) {
        try {
            advice.getAdviceMethod().invoke(advice.getAspect());
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    public Object getProxy() {
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), config.getTargetClass().getInterfaces(), this);
    }
}
